home *** CD-ROM | disk | FTP | other *** search
- #define IGNORE_STDIO_STUBS
- #define __string_h
-
- #ifdef OLDGCC
-
- #include <Common.h>
- #include <System/SysAll.h>
- #include <UI/UIAll.h>
- #include <Unix/sys_types.h>
-
- #else
-
- #include <PalmOS.h>
- #include <PalmCompatibility.h>
- #include <Unix/sys_types.h>
-
- #endif
-
- #include "stringil.h"
- #include "stdio2.h"
- #include "zlib.h"
-
- #ifdef __PALMOS_TRAPS__
- Err errno;
- #endif
-
- int fgetc(FILE * fp)
- {
- unsigned char lastchr;
- if (1 == fread(&lastchr, 1, 1, fp))
- return lastchr;
- else
- return -1;
- }
-
- FILE *fopen(char *name, char *mode)
- {
- // Modes need lots of work
- return FileOpen(0, name, 'DATA', 'NZIP',
- (*mode == 'r' ? fileModeReadOnly : fileModeReadWrite)
- | fileModeAnyTypeCreator, NULL);
- }
-
- #define STORED 0 /* compression methods */
- #define DEFLATED 8
-
- # define CRCVAL_INITIAL 0L
-
- /* PKZIP header definitions */
- #define ZIPMAG 0x4b50 /* two-byte zip lead-in */
- #define LOCREM 0x0403 /* remaining two bytes in zip signature */
- #define LOCSIG 0x04034b50L /* full signature */
- #define LOCFLG 4 /* offset of bit flag */
- #define CRPFLG 1 /* bit for encrypted entry */
- #define EXTFLG 8 /* bit for extended local header */
- #define LOCHOW 6 /* offset of compression method */
- #define LOCTIM 8 /* file mod time (for decryption) */
- #define LOCCRC 12 /* offset of crc */
- #define LOCSIZ 16 /* offset of compressed size */
- #define LOCLEN 20 /* offset of uncompressed length */
- #define LOCFIL 24 /* offset of file name field length */
- #define LOCEXT 26 /* offset of extra field length */
- #define LOCHDR 28 /* size of local header, including LOCREM */
- #define EXTHDR 16 /* size of extended local header, inc sig */
-
- /* GZIP header definitions */
- #define GZPMAG 0x8b1f /* two-byte gzip lead-in */
- #define GZPHOW 0 /* offset of method number */
- #define GZPFLG 1 /* offset of gzip flags */
- #define GZPMUL 2 /* bit for multiple-part gzip file */
- #define GZPISX 4 /* bit for extra field present */
- #define GZPISF 8 /* bit for filename present */
- #define GZPISC 16 /* bit for comment present */
- #define GZPISE 32 /* bit for encryption */
- #define GZPTIM 2 /* offset of Unix file modification time */
- #define GZPEXF 6 /* offset of extra flags */
- #define GZPCOS 7 /* offset of operating system compressed on */
- #define GZPHDR 8 /* length of minimal gzip header */
-
- /* Macros for getting two-byte and four-byte header values */
- #define SH(p) ((unsigned short int)(unsigned char)((p)[0]) | ((unsigned short int)(unsigned char)((p)[1]) << 8))
- #define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16))
-
- /* Globals */
-
- #define BSIZ 128
-
- #define err(n, m) {fprintf(stderr,m );return n;}
-
- int unzipdir(FILE * infile, char *dir, long int *loc)
- {
- int encrypted; /* flag to turn on decryption */
- unsigned long total;
- unsigned short int n;
- unsigned char h[LOCHDR]; /* first local header (GZPHDR < LOCHDR) */
- unsigned char ibuf[BSIZ];
- char *c;
- int max;
-
- *dir = 0;
- dir[1] = 0;
- max = 0;
-
- fseek(infile, 0, SEEK_SET);
-
- /* read ZIPal header, check validity */
- n = fgetc(infile);
- if (n > 255 || feof(infile))
- return 0;
- n |= fgetc(infile) << 8;
-
- if (n != ZIPMAG)
- return 0;
-
- fseek(infile, 0, SEEK_SET);
-
- for (;;) {
- /* read local header, check validity, and skip name and extra fields */
- n = fgetc(infile);
- if (n > 255 || feof(infile))
- return max;
-
- n |= fgetc(infile) << 8;
-
- if (n != ZIPMAG)
- return max;
-
- *loc++ = ftell(infile) - 2L;
-
- fread((char *) h, 1, LOCHDR, infile);
- if (SH(h) == 0x0201)
- return max; // start of central directory
- if (SH(h) != LOCREM)
- err(3, "invalid zipfile");
-
- /* FILENAME */
- ibuf[SH(h + LOCFIL)] = 0;
- fread(ibuf, 1, SH(h + LOCFIL), infile);
-
- for (n = SH(h + LOCEXT); n--;)
- fgetc(infile);
- encrypted = h[LOCFLG] & CRPFLG;
-
- total = LG(h + LOCSIZ);
- c = ibuf;
- while (*c) {
- if (*c <= ' ' || *c >= 0x7f)
- *c = '_';
- c++;
- }
- c = ibuf;
- if (strlen(ibuf) > 32)
- c += strlen(ibuf) - 32;
-
- strcpy(dir,c);
- dir += strlen(c)+1;
- *dir = 0;
-
- /* if entry encrypted, decrypt and validate encryption header */
- if (encrypted)
- err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
-
- fseek(infile, total, SEEK_CUR);
-
- /* if extended header, get it */
- if ((h[LOCFLG] & EXTFLG) &&
- fread((char *) h + LOCCRC - 4, 1, EXTHDR, infile) != EXTHDR)
- err(3, "zipfile ended prematurely");
-
- max++;
-
- }
-
- }
-
-
-
-
- int unzip(FILE * infile, long int loc)
- {
- FILE *outfile;
- unsigned long crc32val;
- unsigned long outsiz; /* total bytes written to out */
- int encrypted; /* flag to turn on decryption */
- unsigned long total, itot;
- unsigned short int n;
- unsigned char h[LOCHDR]; /* first local header (GZPHDR < LOCHDR) */
- int k = 0, got;
- unsigned char ibuf[BSIZ], obuf[BSIZ];
- z_stream pgpz;
- int gz = 0; /* true if gzip format */
- char *c;
- RectangleType r;
-
- fseek(infile, 0, SEEK_SET);
- /* read ZIPal header, check validity */
- n = fgetc(infile);
- if (n > 255 || feof(infile))
- return 0;
- n |= fgetc(infile) << 8;
-
- if (n != ZIPMAG && n != GZPMAG)
- return -1;
-
- if( loc == -1 ) {
- fseek(infile, 0, SEEK_SET);
- FileControl(fileOpDestructiveReadMode, infile, NULL, NULL);
- }
- else
- fseek(infile, loc, SEEK_SET);
-
- for (;;) {
-
- /* read local header, check validity, and skip name and extra fields */
- n = fgetc(infile);
- if (n > 255 || feof(infile))
- return 0;
-
- n |= fgetc(infile) << 8;
-
- r.topLeft.x = 0, r.topLeft.y = 15, r.extent.x = 160, r.extent.y = 30;
- WinEraseRectangle(&r, 0);
-
- if (n == ZIPMAG) {
- fread((char *) h, 1, LOCHDR, infile);
- if (SH(h) == 0x0201)
- return 0; // start of central directory
- if (SH(h) != LOCREM)
- err(3, "invalid zipfile");
- if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
- err(3, "entry not deflated or stored--cannot unpack");
-
- /* FILENAME */
- ibuf[SH(h + LOCFIL)] = 0;
- fread(ibuf, 1, SH(h + LOCFIL), infile);
-
- for (n = SH(h + LOCEXT); n--;)
- gz = fgetc(infile);
- gz = 0;
- encrypted = h[LOCFLG] & CRPFLG;
- }
-
- else if (n == GZPMAG) {
- fread((char *) h, 1, GZPHDR, infile);
- if ((h[GZPHOW] != DEFLATED) || (h[GZPFLG] & GZPMUL))
- err(3, "cannot handle this gzip file");
-
- if (h[GZPFLG] & GZPISX) {
- n = fgetc(infile);
- n |= fgetc(infile) << 8;
- fread(ibuf, 1, n, infile);
- }
-
- if (h[GZPFLG] & GZPISF) {
- c = ibuf;
- while ((*c++ = fgetc(infile)) != 0);
- } else {
- strcpy(ibuf, "gzipun-");
- StrIToA(&ibuf[7], TimGetSeconds());
- strcat(ibuf,".tar");
- }
-
- if (h[GZPFLG] & GZPISC)
- while ((gz = fgetc(infile)) != 0 && gz != -1);
-
- gz = 1;
- encrypted = h[GZPFLG] & GZPISE;
- }
-
- else
- return 1;
-
- total = gz ? 0x7fffffff : LG(h + LOCSIZ);
- if (!total) {
- if( loc == -1 )
- continue;
- else
- return -1;
- }
-
- /* fix filename and open for write */
- c = ibuf;
- while (*c) {
- if (*c <= ' ' || *c >= 0x7f)
- *c = '_';
- c++;
- }
- c = ibuf;
- if (strlen(ibuf) > 32)
- c += strlen(ibuf) - 32;
- outfile = fopen(c, "w");
- WinDrawChars(c, strlen(c), 0, 15);
-
-
- /* if entry encrypted, decrypt and validate encryption header */
- if (encrypted)
- err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
-
- itot = total;
- outsiz = 0L;
- crc32val = CRCVAL_INITIAL;
-
- r.topLeft.y = 30, r.extent.y = 15;
-
- /* decompress */
- if (gz || h[LOCHOW]) { /* deflated entry */
- outsiz = 0;
- memset(&pgpz, 0, sizeof(pgpz));
- inflateInit2(&pgpz, -15);
-
- do {
- while (total && !feof(infile)) {
-
- if (0 > (got = fread(ibuf, 1, total > BSIZ ? BSIZ : total, infile)))
- break;
-
- total -= got;
- if (gz)
- WinDrawChars( gz++ & 1 ? "\\" : "/" , 1, 0, 30);
- else {
- r.extent.x = 160 - (160 * total / itot);
- WinDrawRectangle(&r, 0);
- }
- pgpz.next_in = ibuf;
- pgpz.avail_in = got;
- while (pgpz.avail_in || !total || feof(infile)) {
- pgpz.next_out = obuf;
- pgpz.avail_out = BSIZ;
- k = inflate(&pgpz, !total || !feof(infile) ? 0 : Z_FINISH);
- fwrite(obuf, 1, BSIZ - pgpz.avail_out, outfile);
-
- outsiz += BSIZ - pgpz.avail_out;
- crc32val = crc32(crc32val, obuf, BSIZ - pgpz.avail_out);
-
- if (k == Z_BUF_ERROR && pgpz.avail_out != BSIZ
- && (total || feof(infile))) continue; /* for undoc zlib */
- if (k != Z_OK)
- break;
- }
- }
- } while (total && !feof(infile));
- inflateEnd(&pgpz);
-
- //error status: (k == Z_STREAM_END);
- }
-
-
- else { /* stored entry */
-
- got = LG(h + LOCLEN);
- if (got != LG(h + LOCSIZ))
- err(4, "invalid compressed data--length mismatch");
-
- total = got;
- while (total) {
- got = fread(ibuf, 1, total > BSIZ ? BSIZ : total, infile);
- outsiz += got;
- total -= got;
- r.extent.x = 160 - (160 * total / itot);
- WinDrawRectangle(&r, 0);
- crc32val = crc32(crc32val, ibuf, got);
-
- fwrite(ibuf, 1, got, outfile);
- }
- }
- fclose(outfile);
-
- /* if extended header, get it */
- if (gz) {
- if (pgpz.avail_in < 8)
- err(3, "gzip ended prematurely");
- memcpy((char *) h + LOCCRC, pgpz.next_in, 8);
-
- break; //THIS DOESN'T WORK HERE
- }
- else
- if ((h[LOCFLG] & EXTFLG) &&
- fread((char *) h + LOCCRC - 4, 1, EXTHDR, infile) != EXTHDR)
- err(3, "zipfile ended prematurely");
-
- /* validate decompression */
- if (LG(h + LOCCRC) != crc32val)
- err(4, "invalid compressed data--crc error");
-
- if (LG((gz ? (h + LOCSIZ) : (h + LOCLEN))) != outsiz)
- err(4, "invalid compressed data--length error");
-
- if( loc != -1 )
- break;
-
- }
-
- return 0;
- }
-